#ifndef __PUBLIC_H
#define __PUBLIC_H

#include "list.h"
#include "rbtree.h"
#include "pid_handle.h"
#include <linux/connector.h>

#define PAGE_SIZE   4096
#define MAX_MSGSIZE 1024

#ifndef SOL_NETLINK
#define SOL_NETLINK 270
#endif

/* linux/connector.h should define this */
#ifndef K2OS_RELATE 
#define CN_IDX_RELATE		0xa
#define CN_VAL_RELATE		0x1
#define CN_IDX_RELATE_TOKERNEL 0x10
#define CN_VAL_RELATE_TOKERNEL 0x1
#endif

#define RELEN 128
#define PATHLEN RELEN

#ifndef RELATE_MAGIC
#define RELATE_MAGIC ('k' + '2' + 'o' + 's')
#endif
/* user relate */
extern struct list_head user_relate;
/* other relate */
extern struct list_head task_relate;

//#define RELATE_DEBUG_PRINTF

#ifdef RELATE_DEBUG_PRINTF
#define RDprint(x...)  printf(x)
#else
#define RDprint(x...)
#endif

#define get_task_struct(p) ++p->usage;
#define put_task_struct(p) --p->usage;

struct user_message{
	int magic;
	int cpu;
	int refcount;
	int uid;
    int debug;
	enum {
		KERN_FORK = 1,
		KERN_EXEC = 2,
		KERN_EXIT = 3,
		/* reserved for others */
		USER_ADD_NAME_P = 11,	/* name pid */
		USER_ADD_NAME_R,	/* name rname */
		UAER_ADD_PID_N, 	/* pid numa */
		USER_DEL_PID,   	/* DEL PID */
		USER_DEL_NAME,	    /* DEL NAME */
		USER_SET_NAME_N, 	/* name numa */
        USER_SHOW_LIST_ALL, /* SHOW ALL */
        USER_SHOW_LIST_PID, /* SHOW PID */

        /* user command */
        USER_COMMAND_OFF = 21, /* shutdown recording the relate */
        USER_COMMAND_ON,      /* turn on the recording */
        USER_RESET,         /* reset user_config list */
	} what;
	union {	/* data segment */
	/* KERN_FORK */
		struct kern_fork{
			pid_t ppid;
			pid_t cpid;
		} fork;
	/* KERN_EXEC */
		struct kern_exec{
			pid_t pid;
			char path[RELEN];
		} exec;
	/* KERN EXIT */
		struct kern_exit{
			pid_t pid;
		} exit;
	/* USER add name-pid */
		struct uanp {
			pid_t pid;
			char name[RELEN];
		} uanp;
	/* USER add name-numa */
		struct uann {
			int numaid;
			char name[RELEN];
		} uann;
	/* user add name-rname */
		struct uanr {
			char name[RELEN];
			char rname[RELEN];
			int numaid;
		} uanr;
	/* user set pid-numa */
		struct uapn {
			pid_t pid;
			int numaid;
		} uapn;
	/* user del pid-name */
		struct udpn {
			pid_t pid;
			char path[RELEN];
		} udpn;
    /* show */
        struct show {
            int pid;
            int request_pid;
            char path[RELEN];
        } show;
	} u;
};

#define MAX_ENTRY 255
/* kernel use */
struct user_config {
		int numaid;
		/* when the first process attach to this uc's latest cpu*/
		int latestcpu;
		char name[RELEN];
		char *path[MAX_ENTRY];
		struct list_head list;
		struct list_head head;
		int refcount;
		int uid;
};
#define NONE_RELATE 0
#define EXEC_RELATE 1
#define USER_RELATE 2
#define SHM_RELATE  3
#define PIPE_RELATE 4
struct lb_config {
		char name[RELEN];
		uid_t uid;
		long time;
		int m_consume;
		int c_consume;
		int type;
		/* stub of task list */
		struct list_head head;
		/* node of lb_cofig list */
		struct list_head list;
//		spinlock_t	lock;
		int refcount;
};

struct task_struct {
	int pid;
    int usage;
    int uid;
	char name[RELEN];
	struct task_relate *tr;
    struct rb_node node;
};

struct task_relate {
		/* to the task */
		struct task_struct *p;

		struct list_head exec_relate;
		struct lb_config *exec_lbc;

		struct list_head shm_relate;
		struct lb_config *shm_lbc;

		struct list_head pipe_relate;
		struct lb_config *pipe_lbc;

		struct list_head user_relate;
		struct user_config *user_lbc;
};
/* head tasks list */


extern void validate_all_pids(FILE *fp);
extern void change_cn_proc_mode(int mode);
extern void exit_relate(int pid);
extern int relate_main(void);
/* used for EXEC/PIPE/SHM ... */
extern struct list_head task_relate;
/* used for user lbconfig */
extern struct list_head user_relate;
#endif
